using System;
using Castle.ActiveRecord;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using NHibernate.Criterion;

/*	Table : SessionItems
 *	Columns:	Id       : uniqueidentifier
 *				ItemData : image
 *				SessionId: char(50)
 *				[Key]	 : nvarchar(50)
 */

namespace AgileJedi.MemcachedForMonorail
{
	/// <summary>
	/// Used to persist session items to a database
	/// </summary>	
	public class ARSessionItem
	{
		private static BinaryFormatter serializer = new BinaryFormatter();

		public ARSessionItem()
		{

		}

		public ARSessionItem(Guid sessionId, string key, Object value)
		{
			this._sessionId = sessionId;
			this.Key = key;
			this.Value = value;
		}

		private Guid _id = Guid.NewGuid();
		[PrimaryKey(PrimaryKeyType.Assigned, Access = PropertyAccess.NosetterLowercaseUnderscore)]
		public virtual Guid Id
		{
			get { return _id; }			
		}


		[Property(Access = PropertyAccess.Property, ColumnType = "BinaryBlob",SqlType="image", NotNull = false)]
		public virtual byte[] ItemData
		{
			get
			{
                if(_value == null )
                    return null;
                
				MemoryStream stream = new MemoryStream();
				serializer.Serialize(stream, _value);
				return stream.ToArray();
			}
			set
			{
				MemoryStream stream = new MemoryStream(value);
				_value = (Object)serializer.Deserialize(stream);
			}
		}

		private object _value = null;
		public virtual object Value
		{
			get { 
                
                return _value ; 
            }
            set
            {
                _value = value;
               
            }
		}
         
		private Guid _sessionId;
		[Property(UniqueKey = "SessionIdKey", NotNull = true)]
		public virtual Guid SessionId
		{
			get { return _sessionId; }
			set { _sessionId = value; }
		}

		private string _key;
		[Property("ItemKey", UniqueKey = "SessionIdKey", NotNull=true)]
		public virtual string Key
		{
			get { return _key; }
			set { _key = value; }
		}

		internal static ARSessionItem Find(Guid sessionId, string key)
		{
			return ActiveRecordMediator.FindOne(typeof(ARSessionItem), Restrictions.And(Restrictions.Eq("SessionId", sessionId), Restrictions.Eq("Key", key))) as ARSessionItem;
		}

		internal virtual void Create()
		{
			ActiveRecordMediator<ARSessionItem>.Create(this);
		}

		internal virtual void Remove()
		{
			ActiveRecordMediator<ARSessionItem>.Delete(this);
		}

		internal  static void Remove(Guid sessionid, string key)
		{
			ActiveRecordMediator<ARSessionItem>.DeleteAll(typeof(ARSessionItem), String.Format("SessionId = '{0}' AND ItemKey = '{1}'",sessionid, key));

		}

		internal  static void RemoveSession(Guid guid)
		{
			ActiveRecordMediator<ARSessionItem>.DeleteAll(typeof(ARSessionItem), "SessionId = '" + guid + "'");
		}
	}
}